package com.utils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateUtils {
	
	public static long ONEDAY_MILLIS = 24 * 3600 * 1000;//一天的毫秒
	public static long ONEDAY_SECOND = 24 * 3600;//一天的秒钟
	
	public static boolean inToday(long millis){
		long start = todayStart();
		long end = todayEnd();
		return start <= millis && end>=millis;
	}
	
	public static long todayStart(){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		long start = calendar.getTimeInMillis();
		return start;
	}
	
	public static long todayEnd(){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		long end = calendar.getTimeInMillis();
		return end;
	}
	/**
	 * 获取某一时间戳的当天的24点时间戳
	 */
	public static long oneDayEnd(long time){
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(time);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		long end = calendar.getTimeInMillis();
		return end;
	}
	
	public static boolean isSameMonth(long millis1, long millis2){
		Calendar calendar1 = Calendar.getInstance();
		Calendar calendar2 = Calendar.getInstance();
		
		calendar1.setTimeInMillis(millis1);
		calendar2.setTimeInMillis(millis2);
		
		return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR) &&  calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
	}
	
	public static boolean isNeerDay(long millis1, long millis2){
		Calendar calendar1 = Calendar.getInstance();
		Calendar calendar2 = Calendar.getInstance();
		calendar1.setTimeInMillis(millis1);
		calendar2.setTimeInMillis(millis2);
		
		calendar1.set(Calendar.HOUR_OF_DAY, 0);
		calendar1.set(Calendar.MINUTE, 0);
		calendar1.set(Calendar.SECOND, 0);
		calendar1.set(Calendar.MILLISECOND, 0);
		
		calendar2.set(Calendar.HOUR_OF_DAY, 0);
		calendar2.set(Calendar.MINUTE, 0);
		calendar2.set(Calendar.SECOND, 0);
		calendar2.set(Calendar.MILLISECOND, 0);

//		return (Math.abs(calendar1.getTimeInMillis()/ONEDAY_MILLIS - calendar2.getTimeInMillis()/ONEDAY_MILLIS) <= 1);
		return (Math.abs(calendar1.getTimeInMillis() - calendar2.getTimeInMillis()) <= ONEDAY_MILLIS);
	}
	
	public static int getDayFromTimeStampBegin(long millis1)
	{
		return (int)(millis1/3600000/24);
	}
	
	public static String dateFormat(long millis, String format){
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		SimpleDateFormat df = new SimpleDateFormat(format);
		return df.format(cal.getTime());
	}
	
	public static String cnDateFormat(long millis){
		return dateFormat(millis, "yyyy-MM-dd HH:mm:ss");
	}
	
	/**
	 * 月里的天
	 * @return
	 */
	public static int getDayOfMonth()
	{
		return getDayOfMonth(System.currentTimeMillis());
	}
	
	public static int getDayOfMonth(long millis)
	{
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.DAY_OF_MONTH);
	}
	
	/**
	 * 获取当前时间的秒
	 * @return
	 */
	public static int getNowSecond()
	{
		return (int) (System.currentTimeMillis() / 1000);
	}
	
	/**
	 * 星期几
	 * @return
	 */
	public static int getDayOfWeek()
	{
		return getDayOfWeek(System.currentTimeMillis());
	}
	
	public static int getDayOfWeek(long millis)
	{
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.DAY_OF_WEEK);
	}
	/**
	 * 几月
	 * @return
	 */
	public static int getMonth()
	{
		return getMonth(System.currentTimeMillis());
	}
	
	public static int getMonth(long millis)
	{
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.MONTH) + 1;//月从0开始
	}
	/**
	 * 获取小时.
	 * @return
	 */
	public static int getHourOfDay()
	{
		return getHourOfDay(System.currentTimeMillis());
	}
	
	public static int getHourOfDay(long millis)
	{
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获取小时.
	 * 
	 * @return
	 */
	public static int getMinuteOfDay() {
		return getMinuteOfDay(System.currentTimeMillis());
	}

	public static int getMinuteOfDay(long millis) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.MINUTE);
	}

	/**
	 * 获取小时.
	 * 
	 * @return
	 */
	public static int getSecondOfDay() {
		return getSecondOfDay(System.currentTimeMillis());
	}

	public static int getSecondOfDay(long millis) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.SECOND);
	}

	public static int getWeekOfMonth(long millis) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.WEEK_OF_MONTH);
	}
	
	/**
	 * 获取今天之前的日期
	 * @param dayIndex 前多少天
	 * @return
	 */
	public static Date getSpecifiedDayBefore(int dayIndex) {
		Calendar c = Calendar.getInstance();
		Date date =new Date(System.currentTimeMillis());
		c.setTime(date);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day - dayIndex);
		return c.getTime();
	}
	
	public static String getWeekKey(){
		return getWeekKey(Calendar.MONDAY);
	}
	
	public static String getWeekKey(int weekDay){
		String key = "w-";
		Calendar cal = Calendar.getInstance();
		//今天就是周六
		if (cal.get(Calendar.DAY_OF_WEEK) == weekDay) {
			key += new SimpleDateFormat("dd").format(new Date());
		} else { //今天非周六，查找上个周六的日期
			int dayIndex = 1;
			Calendar beforeCal = Calendar.getInstance();
			while(dayIndex <= 6) { //向前6天开始查找上周六的日期
				Date beforeDay = getSpecifiedDayBefore(dayIndex);
				beforeCal.setTime(beforeDay);
				if(beforeCal.get(Calendar.DAY_OF_WEEK) == weekDay) {
					key += new SimpleDateFormat("dd").format(beforeDay);
					break;
				}
				dayIndex++;
			}
		}
		return key;
	}
	
	
	/*public static Date getSpecifiedDayAfter(int dayIndex) {
		Calendar c = Calendar.getInstance();
		Date date =new Date(System.currentTimeMillis());
		c.setTime(date);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day + dayIndex);
		return c.getTime();
	}
	
	public static List<Integer> getTwoDayBetween(int startDay,int endDay){
		if(startDay == endDay) return null;
		List<Integer> dataList = null;
		try {
			dataList = new ArrayList<Integer>(2);
			Calendar cal = Calendar.getInstance();
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			//System.out.println(new Date() + " " + cal.get(Calendar.DAY_OF_WEEK));
			//今天就是startDay
			if (cal.get(Calendar.DAY_OF_WEEK) == startDay) {
				dataList.add((int)(simpleDateFormat.parse(dateFormat.format(new Date()) + " 00:00:00").getTime()/1000));
			} else { //今天非startDay，查找上个startDay的日期
				int dayIndex = 1;
				while(dayIndex <= 6) { //向前6天开始查找上周六的日期
					Date beforeDay = getSpecifiedDayBefore(dayIndex);
					cal.setTime(beforeDay);
					if(cal.get(Calendar.DAY_OF_WEEK) == startDay) {
						dataList.add((int)(simpleDateFormat.parse(dateFormat.format(beforeDay) + " 00:00:00").getTime()/1000));
						break;
					}
					dayIndex++;
				}
			}
			
			Calendar calend = Calendar.getInstance();
			//今天就是endDay
			if (calend.get(Calendar.DAY_OF_WEEK) == endDay) {
				dataList.add((int)(simpleDateFormat.parse(dateFormat.format(new Date()) + " 23:59:59").getTime()/1000));
			} else { //今天非startDay，查找上个startDay的日期
				int dayIndex = 1;
				while(dayIndex <= 6) { //向前6天开始查找上周六的日期
					Date afterDay = getSpecifiedDayAfter(dayIndex);
					calend.setTime(afterDay);
					if(calend.get(Calendar.DAY_OF_WEEK) == endDay) {
						dataList.add((int)(simpleDateFormat.parse(dateFormat.format(afterDay) + " 23:59:59").getTime()/1000));
						break;
					}
					dayIndex++;
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}
		return dataList;
	}*/
	
	/**
	 * 获取本周的时间范围（周一至周日）
	 * @return
	 */
    public static List<Integer> getTwoDayBetween() {
        List<Integer> dataList = new ArrayList<Integer>(2);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
        	Calendar calendar = Calendar.getInstance();
            calendar.setFirstDayOfWeek(Calendar.MONDAY);//设置周一为一周之内的第一天
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
            dataList.add((int)(simpleDateFormat.parse(dateFormat.format(calendar.getTime()) + " 00:00:00").getTime()/1000));
            calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
            dataList.add((int)(simpleDateFormat.parse(dateFormat.format(calendar.getTime()) + " 23:59:59").getTime()/1000));
		} catch (Exception e) {}
        return dataList;
    }
	
	/**
	 * 获取今天到凌晨12点的时间间隔
	 * 
	 * @return
	 */
	public static long getTodayRemain() {
		return DateUtils.todayEnd() - System.currentTimeMillis();
	}
    
    public static String getNowFormatTime() {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
		return df.format(new Date());// new Date()为获取当前系统时间
	}

	public static String getNowFormatDate() {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");// 设置日期格式
		return df.format(new Date());// new Date()为获取当前系统时间
	}

	public static String getFormateDate(long time) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");// 设置日期格式
		return df.format(new Date(time));
	}

//	public static boolean isThisWeek(long time) {
//		Calendar calendar = Calendar.getInstance();
//		int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
//		calendar.setTime(new Date(time));
//		int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
//		if (paramWeek == currentWeek) {
//			return true;
//		}
//		return false;
//	}


	public static boolean isThisWeek(long millins) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.MONDAY);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		int monday = Integer.valueOf(cal.get(Calendar.YEAR)+ "" + (cal.get(Calendar.MONTH) + 1) + "" + cal.get(Calendar.DAY_OF_MONTH));
		cal.setTimeInMillis(millins);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		int thisDay = Integer.valueOf(cal.get(Calendar.YEAR)+ "" + (cal.get(Calendar.MONTH) + 1) + "" + cal.get(Calendar.DAY_OF_MONTH));
		if(monday == thisDay){
			return true;
		}
		return false;
	}

	public static int getMonthOfYear() {
		return getMonthOfYear(System.currentTimeMillis());
	}

	public static int getMonthOfYear(long millis) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.MONTH);
	}
	/**
     * 判断两个时间戳相隔几个月
     * @param args
     */
    public static int getMonthDiff(long beforeTime, long afterTime){
    	try{
	        Calendar bef = Calendar.getInstance();
	        Calendar aft = Calendar.getInstance();
	        bef.setTimeInMillis(beforeTime);
	        aft.setTimeInMillis(afterTime);
	        int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
	        int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
	        return Math.abs(month + result);
		}catch(Exception e){}
    	return -1;
    }
    /**
     * 获取某个时间所处当月最后一天的时间戳
     */
    public static long getMonthEndTime(long time){
    	SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTimeInMillis(time);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));  
        String endTime = dft.format(calendar.getTime());
        try{
        	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        	Date date = df.parse(endTime + " 23:59:59");
        	return date.getTime();
        }catch(Exception e){}
        return -1;
    }
    /**
     * 获取某个时间下个月第一天的时间戳
     */
    public static long getNextMonthStartTime(long time){
    	SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTimeInMillis(time);
        calendar.add(Calendar.MONTH, 1);  
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));  
        String startTime = dft.format(calendar.getTime());
        try{
        	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        	Date date = df.parse(startTime + " 00:00:00");
        	return date.getTime();
        }catch(Exception e){}
        return -1;
    }
    /**
     * 获取某个时间当月第一天的时间戳
     */
    public static long getCurMonthStartTime(long time){
    	SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTimeInMillis(time); 
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));  
        String startTime = dft.format(calendar.getTime());
        try{
        	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        	Date date = df.parse(startTime + " 00:00:00");
        	return date.getTime();
        }catch(Exception e){}
        return -1;
    }
    /**
	 * 获取当天剩余的秒数
	 * @return
	 */
	public static int getTodayRemainSec(){
		int nowTime = (int)(System.currentTimeMillis()/1000);
		int endTime = (int)(todayEnd()/1000)+1;
		return endTime-nowTime;
	}
	
	public static int getAppointRemainSec(int dayIndex){
		int nowTime = (int)(System.currentTimeMillis()/1000);
		int endTime = (int)(getAppointDay(dayIndex)/1000)+1;
		return endTime-nowTime;
	}
	
	/**
	 * 
	 * @param dayIndex 0 今天结束时间  1 明天结束时间 2 后天结束时间
	 * @return
	 */
	public static long getAppointDay(int dayIndex) {
		Calendar c = Calendar.getInstance();
		Date date =new Date(System.currentTimeMillis());
		c.setTime(date);
		int day = c.get(Calendar.DATE);
		c.set(Calendar.DATE, day + dayIndex);
		
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		c.set(Calendar.MILLISECOND, 999);
		return c.getTimeInMillis();
	}
	
	/**
	 * 是否是同一周
	 * @return
	 */
	public static boolean isSameWeek(long millis1, long millis2){
		Calendar calendar1 = Calendar.getInstance();
		Calendar calendar2 = Calendar.getInstance();
		
		calendar1.setTimeInMillis(millis1 - ONEDAY_MILLIS);//西方默认是周日为一周的开始
		calendar2.setTimeInMillis(millis2 - ONEDAY_MILLIS);
		
		return calendar1.get(Calendar.WEEK_OF_YEAR) == calendar2.get(Calendar.WEEK_OF_YEAR);
	}
	
	public static int getMsOfDay()
	{
		return getMsOfDay(System.currentTimeMillis());
	}
	
	public static int getMsOfDay(long millis)
	{
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(millis);
		return cal.get(Calendar.SECOND);
	}
	
	public static long getFormatNows(long now){
		int mills = (int)(now/1000);
		long nowt = now;
		try{
			nowt = Long.parseLong(mills+"000");
		}catch(Exception e){
		}
		return nowt;
	}
	/**
	 * 获取N个月前/后的第一天时间戳
	 * @param preMonth
	 * @return
	 */
	public static long getNowMulMonthTime(int mulMonth){
		SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");  
        Calendar calendar = Calendar.getInstance();  
        calendar.add(Calendar.MONTH, mulMonth);
        String time = dft.format(calendar.getTime());
        try{
        	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        	Date date = df.parse(time + " 00:00:00");
        	long firstTime = getCurMonthStartTime(date.getTime());
        	return firstTime;
        }catch(Exception e){}
        return 0;
	}
	
	public static void main(String []args){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try{
			Date startTime = format.parse("2020-03-01 00:00:00");
			Date endTime = format.parse("2020-03-03 23:59:59");
			System.out.println(startTime.getTime()+" "+endTime.getTime());
			System.out.println(83886214<<8>>8);
			System.out.println(getDayDiff(startTime.getTime(), endTime.getTime()));
		}catch(Exception e){
			
		}
		
	}
	/**
	 * 获取相差天数
	 * @param millis1
	 * @param millis2
	 * @return
	 */
	public static int getDayDiff(long millis1, long millis2){
		Calendar calendar1 = Calendar.getInstance();
		Calendar calendar2 = Calendar.getInstance();
		calendar1.setTimeInMillis(millis1);
		calendar2.setTimeInMillis(millis2);
		
		calendar1.set(Calendar.HOUR_OF_DAY, 0);
		calendar1.set(Calendar.MINUTE, 0);
		calendar1.set(Calendar.SECOND, 0);
		calendar1.set(Calendar.MILLISECOND, 0);
		
		calendar2.set(Calendar.HOUR_OF_DAY, 0);
		calendar2.set(Calendar.MINUTE, 0);
		calendar2.set(Calendar.SECOND, 0);
		calendar2.set(Calendar.MILLISECOND, 0);

		return (int) (Math.abs(calendar1.getTimeInMillis() - calendar2.getTimeInMillis()) / ONEDAY_MILLIS);
	}
}
